using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Avalonia.Controls;
using Avalonia.Controls.Notifications;
using Avalonia.Controls.Primitives;
using Avalonia.Threading;
using FluentAvalonia.UI.Windowing;
using iOSClub.App.Desktop.Models;
using iOSClub.App.Desktop.Pages;
using iOSClub.App.Share;
using iOSClub.App.Share.Serves;
using LiveChartsCore;
using Newtonsoft.Json;

namespace iOSClub.App.Desktop.Views;

public partial class MainWindow : AppWindow
{
    private DataWindow Data { get; } = new();

    public MainWindow(SettingModel settingModel)
    {
        Setting = settingModel;
        InitializeComponent();
        SplashScreen = new MainAppSplashScreen("iOS Club App", InitApp);
        TitleBar.ExtendsContentIntoTitleBar = true;
        TitleBar.TitleBarHitTestType = TitleBarHitTestType.Complex;

        Data.Closing += (s, e) =>
        {
            ((Window)s!).Hide();
            e.Cancel = true;
        };
    }

    private SettingModel Setting { get; set; }

    private WindowNotificationManager? _manager;

    private async void InitApp()
    {
        using UserServer http = new();

        if (string.IsNullOrEmpty(Setting.Id))
        {
            Dispatcher.UIThread.Post(() => ChangeItem(new LoginView()));
            return;
        }

        var jwt = await http.Login(Setting.ToLogin());
        if (string.IsNullOrEmpty(jwt))
        {
            Dispatcher.UIThread.Post(() => ChangeItem(new LoginView()));
            return;
        }

        var user = await http.GetData();
        if (user == null)
        {
            Dispatcher.UIThread.Post(() => ChangeItem(new LoginView()));
            return;
        }

        DataInit(user, jwt);
    }

    private void DataInit(MemberModel user, string jwt)
    {
        Dispatcher.UIThread.Post(() =>
        {
            var main = new MainView(jwt, user,Setting);
            ChangeItem(main);
        });
    }

    protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
    {
        base.OnApplyTemplate(e);
        _manager = new WindowNotificationManager(this) { MaxItems = 3, Position = NotificationPosition.BottomRight };
    }

    public void NotificationShow(string title, string message, NotificationType type = NotificationType.Information)
    {
        _manager?.Show(new Notification(title, message, type));
    }

    public void ChangeItem(Control control)
    {
        if (Grid.Children.Count > 1)
            Grid.Children.RemoveAt(1);
        Grid.SetRow(control, 1);
        Grid.Children.Add(control);
    }

    public async Task<bool> Login(LoginModel model)
    {
        using UserServer http = new();
        var jwt = await http.Login(model);
        if (string.IsNullOrEmpty(jwt)) return false;
        var user = await http.GetData() ?? new MemberModel();
        if (string.IsNullOrEmpty(user.Gender)) return false;
        DataInit(user, jwt);
        if (Setting.Name == model.Name && Setting.Id == model.Id) return true;
        Setting.Name = model.Name;
        Setting.Id = model.Id;
        await File.WriteAllTextAsync("data.json", JsonConvert.SerializeObject(Setting));
        return true;
    }

    public async Task<bool> SignUp(StudentModel model)
    {
        using UserServer http = new();
        var jwt = await http.SignUp(model);
        if (string.IsNullOrEmpty(jwt)) return false;
        var user = await http.GetData() ?? new MemberModel();
        if (string.IsNullOrEmpty(user.Gender)) return false;
        DataInit(user, jwt);
        Setting.Name = model.UserName;
        Setting.Id = model.UserId;
        await File.WriteAllTextAsync("data.json", JsonConvert.SerializeObject(Setting));
        return true;
    }

    public void Logout()
    {
        ChangeItem(new LoginView(Setting.ToLogin()));
    }

    public void OpenData(IEnumerable<ISeries> data, string title = "")
    {
        Data.Change(data, title);
        Data.Show();
    }

    public void CopyContext(string context, Notification? notification = null)
    {
        Clipboard?.SetTextAsync(context);
        if (notification != null) ShoeNotification(notification);
    }

    private void ShoeNotification(Notification notification)
    {
        _manager?.Show(notification);
    }

    public void ChangeSetting(SettingModel model)
    {
        Setting = model;
        File.WriteAllText("data.json", JsonConvert.SerializeObject(model));
    }
}